using System;
using AndyPike.Presentations.IntroToTDD.Interfaces;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace AndyPike.Presentations.IntroToTDD.Tests
{
    public abstract class StringReverserBase
    {
        protected MockRepository mockery;
        protected IReverser<string> reverser;
        protected ILogger logger;

        [SetUp]
        public virtual void SetUp()
        {
            mockery = new MockRepository();

            logger = mockery.DynamicMock<ILogger>();
        }

        [Test]
        public void Should_return_the_reverse_of_a_valid_string_of_even_length()
        {
            string result = reverser.Reverse("1234567890");

            Assert.That(result, Is.EqualTo("0987654321"));
        }

        [Test]
        public void Should_return_the_reverse_of_a_valid_string_of_odd_length()
        {
            string result = reverser.Reverse("12345678901");

            Assert.That(result, Is.EqualTo("10987654321"));
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Should_throw_an_exception_if_null_is_passed_in()
        {
            reverser.Reverse(null);
        }

        [Test]
        public void Should_return_an_empty_string_if_an_empty_string_is_passed_in()
        {
            string result = reverser.Reverse(string.Empty);

            Assert.That(result, Is.EqualTo(string.Empty));
        }

        [Test]
        public void Should_log_a_successful_reversal()
        {
            using (mockery.Record())
            {
                Expect.Call(() => logger.Info(null)).IgnoreArguments();
            }

            using (mockery.Playback())
            {
                reverser.Reverse("This is a string");
            }           
        }
    }
}